﻿using PMS.Core.Configuration.CommonEnumConfigs;
using PMS.Core.Infrastructure;
using PMS.Core.Utils;
using PMS.Data.Entities.Medias;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;

namespace PMS.Services.EntityServices.Medias
{
    /// <summary>
    /// Represents mimetypes manager
    /// </summary>
    public partial class MimeTypesManager
    {
        #region Fields
        private IMimeTypesService _mimetypesService;
        private readonly List<MimeTypes> _mimetypesList = new List<MimeTypes>();

        #endregion

        #region Ctor

        private MimeTypesManager()
        {
            Initialize();
        }

        #endregion

        #region Utils

        protected MimeTypes GetMatchedMimeTypesRecord(string fileExtName)
        {
            if (string.IsNullOrEmpty(fileExtName))
                throw new ArgumentNullException(nameof(fileExtName));
            if (_mimetypesList.Count <= 0)
                throw new PMSException("MimeTypes Null Exception", SystemLogLevel.Error);
            if (fileExtName.StartsWith("."))
                fileExtName = fileExtName.Substring(1);
            return _mimetypesList.FirstOrDefault(m => m.ExtensionName.Equals(fileExtName, StringComparison.InvariantCultureIgnoreCase));
        }

        #endregion

        #region Methods
        /// <summary>
        /// 按分类获取支持的媒体文件列表,以扩展名形式输出
        /// 用于上传时获取可支持的媒体文件列表
        /// </summary>
        /// <param name="fileType"></param>
        /// <returns>文件扩展名以"."开头,如 .jpg</returns>
        public IList<string> GetSupportFileExtensionsByCategory(MediaFileType fileType = MediaFileType.Image)
        {
            if (_mimetypesList.Count <= 0)
                return null;
            var supportExts = _mimetypesList.Where(m => m.Category.Equals(fileType.ToString(), StringComparison.InvariantCultureIgnoreCase))
                                            .Select(m => "." + m.ExtensionName)
                                            .ToList();
            return supportExts;
        }

        public string GetFileOutputExtNameByMimeType(string mimeType)
        {
            if (string.IsNullOrEmpty(mimeType)) return "";
            return _mimetypesList.FirstOrDefault(m => m.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))?.OutputExtensionName ?? "";
        }

        public MediaFileType GetFileCategoryByMimeType(string mimeType)
        {
            if (string.IsNullOrEmpty(mimeType)) return MediaFileType.Unknown;
            var matchedRecord = _mimetypesList.FirstOrDefault(m => m.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase));
            return CommonHelper.To<MediaFileType>(matchedRecord == null ? nameof(MediaFileType.Unknown) : matchedRecord.Category);
        }
        /// <summary>
        /// 所有上传文件在本地/云存储时统一输出文件名格式
        /// 如.jpg或.jpeg文件保存后输出为.jpg格式
        /// </summary>
        /// <param name="fileExtName">文件扩展名</param>
        /// <returns></returns>
        public string GetFileOutputExtName(string fileExtName)
        {
            var matchedMimetype = GetMatchedMimeTypesRecord(fileExtName);
            return matchedMimetype?.OutputExtensionName ?? "";
        }

        public MediaFileType GetFileCategoryFromExtName(string fileExtName)
        {
            var matchedMimetype = GetMatchedMimeTypesRecord(fileExtName);
            if (matchedMimetype == null) return MediaFileType.Unknown;
            return CommonHelper.To<MediaFileType>(matchedMimetype.Category);
        }

        public string GetFileMimeTypeFromExtName(string fileExtName)
        {
            var matchedMimetype = GetMatchedMimeTypesRecord(fileExtName);
            return matchedMimetype?.MimeType ?? "";
        }
        #endregion

        #region Utility
        /// <summary>
        /// Initializes the mimetypes manager
        /// </summary>
        protected void Initialize()
        {
            _mimetypesList.Clear();
            if (_mimetypesService == null)
                _mimetypesService = EngineContext.Current.Resolve<IMimeTypesService>();

            var cachedMimeTypes = _mimetypesService
                .GetMimeTypesAll()
                .OrderBy(m => m.Category)
                .ToList();
            _mimetypesList.AddRange(cachedMimeTypes);
        }
        #endregion

        #region Properties

        /// <summary>
        /// Gets the mimetypes manger instance
        /// </summary>
        public static MimeTypesManager Instance 
        {
            get
            {
                if (Singleton<MimeTypesManager>.Instance == null)
                {
                    return Create();
                }

                return Singleton<MimeTypesManager>.Instance;
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static MimeTypesManager Create()
        {
            //create NowaEngine as engine
            return Singleton<MimeTypesManager>.Instance ?? (Singleton<MimeTypesManager>.Instance = new MimeTypesManager());
        }

        /// <summary>
        /// Gets a list of task of this task manager
        /// </summary>
        public IList<MimeTypes> ReadOnlyMimeTypes => new ReadOnlyCollection<MimeTypes>(_mimetypesList);

        #endregion
    }
}
